package dating.service;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import dating.model.Persistent;

public abstract class GenericService<E extends Persistent, PK extends Serializable>
		implements GenericServiceLocal<E, PK> {

	@PersistenceContext(unitName = "datingPU")
	protected EntityManager em;

	protected Class<E> entityClass;

	public GenericService(Class<E> entityClass) {
		this.entityClass = entityClass;
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public E save(E entity) {
		try {
			this.em.persist(entity);
		} catch (PersistenceException e) {
			throw new ServiceException("Could not save entity "
					+ this.entityClass.getName(), e);
		}
		return entity;
	};

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public void delete(E entity) {
		try {
			this.em.remove(entity);
		} catch (PersistenceException e) {
			throw new ServiceException("Could not delete entity "
					+ this.entityClass.getName(), e);
		}
	}

	@Override
	public E findByPK(PK key) {
		E entity = null;
		try {
			entity = this.em.find(this.entityClass, key);
		} catch (PersistenceException e) {
			throw new ServiceException("Could not find entity "
					+ this.entityClass.getName() + " with key " + key, e);
		}

		return entity;
	}

	public List<E> findAll() {
		List<E> result = null;
		
		System.out.println("NAME: " + this.entityClass.getName());
		try {
			Query query = this.em.createQuery("from "
					+ this.entityClass.getName());
			result = query.getResultList();
		} catch (PersistenceException e) {
			throw new ServiceException("Could not find entities of type "
					+ this.entityClass.getName(), e);
		}

		if (result == null) {
			result = Collections.emptyList();
		}

		return result;
	}

}
